package com.inight.ojcodesandbox.utils;

import com.inight.ojcodesandbox.model.ExecuteMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StopWatch;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 用于获取控制台输出的信息
 */
public class ProcessUtils {


    /**
     * 执行进程并获取控制台信息
     * @param process
     * @param opName
     * @return
     */
    public static ExecuteMessage runProcessAndGetMessage(Process process, String opName) {

        ExecuteMessage executeMessage = new ExecuteMessage();

        // spring 自带的一个计时器
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        try {
            int exitValue = process.waitFor();
            executeMessage.setExitValue(exitValue);
            // 正常退出
            if (exitValue == 0) {
                System.out.println(opName + "成功");
                // 通过进程获取正常输出到控制台的信息.
                // 读取字符流, 用 BufferedRead 带有缓冲区的字符流效率会更高点
                // https://cloud.tencent.com/developer/article/2409264
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                List<String> outputStrList = new ArrayList<>();
                // 逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    outputStrList.add(compileOutputLine);
                }
                // 将列表中的字符串用换行拼接起来.
                executeMessage.setMessage(StringUtils.join(outputStrList, "\n"));
                System.out.println("工具类获取结果: " + StringUtils.join(outputStrList, "\n"));
            } else {
                // 异常退出
                System.out.println(opName + "失败，错误码：" + exitValue);
                // 通过进程获取正常输出到控制台的信息
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                List<String> outputStrList = new ArrayList<>();
                // 逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    outputStrList.add(compileOutputLine);
                }
                executeMessage.setMessage(StringUtils.join(outputStrList, "\n"));

                // 分批获取进程的错误输出
                BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                List<String> outputErrorStrList = new ArrayList<>();
                // 逐行读取
                String errorCompileOutputLine;
                while ((errorCompileOutputLine = bufferedReader.readLine()) != null) {
                    outputErrorStrList.add(errorCompileOutputLine);
                }
                // 设置错误信息
                executeMessage.setErrorMessage(StringUtils.join(outputErrorStrList, "\n"));
            }
        } catch (InterruptedException | IOException e) {
            // throw new RuntimeException(e);
            // 只是打印一下
            e.printStackTrace();
        }

        stopWatch.stop();
        long lastTaskTimeMillis = stopWatch.getLastTaskTimeMillis();
        executeMessage.setTime(lastTaskTimeMillis);
        return executeMessage;

    }
}